package com.example.dingtalklogin.common.util;

import com.example.dingtalklogin.common.exception.CheckException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.List;

@Slf4j
public class RequestHolder {

    /**
     * 获取request
     *
     * @return HttpServletRequest
     */
    public static HttpServletRequest getRequest() {
        if(log.isDebugEnabled()){
            log.debug("getRequest -- Thread id :{}, name : {}", Thread.currentThread().getId(), Thread.currentThread().getName());
        }
        ServletRequestAttributes servletRequestAttributes = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes());
        if (null == servletRequestAttributes) {
            return null;
        }
        return servletRequestAttributes.getRequest();
    }

    /**
     * 获取Response
     *
     * @return HttpServletRequest
     */
    public static HttpServletResponse getResponse() {
        if(log.isDebugEnabled()){
            log.debug("getResponse -- Thread id :{}, name : {}", Thread.currentThread().getId(), Thread.currentThread().getName());
        }
        ServletRequestAttributes servletRequestAttributes = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes());
        if (null == servletRequestAttributes) {
            return null;
        }
        return servletRequestAttributes.getResponse();
    }

    /**
     * 获取session
     *
     * @return HttpSession
     */
    public static HttpSession getSession() {
        if(log.isDebugEnabled()){
            log.debug("getSession -- Thread id :{}, name : {}", Thread.currentThread().getId(), Thread.currentThread().getName());
        }
        HttpServletRequest request = null;
        if (null == (request = getRequest())) {
            return null;
        }
        return request.getSession();
    }

    /**
     * 获取session的Attribute
     *
     * @param name session的key
     * @return Object
     */
    public static Object getSession(String name) {
        if(log.isDebugEnabled()){
            log.debug("getSession -- Thread id :{}, name : {}", Thread.currentThread().getId(), Thread.currentThread().getName());
        }
        ServletRequestAttributes servletRequestAttributes = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes());
        if (null == servletRequestAttributes) {
            return null;
        }
        return servletRequestAttributes.getAttribute(name, RequestAttributes.SCOPE_SESSION);
    }

    /**
     * 添加session
     *
     * @param name
     * @param value
     */
    public static void setSession(String name, Object value) {
        if(log.isDebugEnabled()){
            log.debug("setSession -- Thread id :{}, name : {}", Thread.currentThread().getId(), Thread.currentThread().getName());
        }
        ServletRequestAttributes servletRequestAttributes = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes());
        if (null == servletRequestAttributes) {
            return;
        }
        servletRequestAttributes.setAttribute(name, value, RequestAttributes.SCOPE_SESSION);
    }

    /**
     * 清除指定session
     *
     * @param name
     * @return void
     */
    public static void removeSession(String name) {
        if(log.isDebugEnabled()){
            log.debug("removeSession -- Thread id :{}, name : {}", Thread.currentThread().getId(), Thread.currentThread().getName());
        }
        ServletRequestAttributes servletRequestAttributes = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes());
        if (null == servletRequestAttributes) {
            return;
        }
        servletRequestAttributes.removeAttribute(name, RequestAttributes.SCOPE_SESSION);
    }

    /**
     * 获取所有session key
     *
     * @return String[]
     */
    public static String[] getSessionKeys() {
        if(log.isDebugEnabled()){
            log.debug("getSessionKeys -- Thread id :{}, name : {}", Thread.currentThread().getId(), Thread.currentThread().getName());
        }
        ServletRequestAttributes servletRequestAttributes = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes());
        if (null == servletRequestAttributes) {
            return null;
        }
        return servletRequestAttributes.getAttributeNames(RequestAttributes.SCOPE_SESSION);
    }

    /**
     * 获取当前请求url 不包含Host和端口以及协议仅
     * /list?name=zhangsan
     * 可以过滤query
     * @param excludeQuery
     * @return
     */
    public static String getBaseURL(String... excludeQuery){
        HttpServletRequest request = RequestHolder.getRequest();

        String queryString  = request.getQueryString() != null
                ? request.getQueryString():"";

        StringBuilder newQueryStringBuilder = new StringBuilder();

        String[] params = queryString.split("&");

        List<String> excludeQueryList = Arrays.asList(excludeQuery);

        for (String param : params) {
            if(!excludeQueryList.stream().anyMatch(q
                    -> param.startsWith(q+"="))){
                newQueryStringBuilder.append("&"+param);
            }
        }

        String url = request.getContextPath() + request.getRequestURI() ;
        if(newQueryStringBuilder.length()>0){
            url+= "?" + newQueryStringBuilder.substring(1);
        }
        return url;
    }

    /**
     * 获取当前请求完整URL
     */
    public static String getURL() {

        HttpServletRequest request = RequestHolder.getRequest();

        return request.getScheme() + "://"
                + request.getServerName()
                + (request.getServerPort() == 80 ? "" : ":" + request.getServerPort())
                + request.getContextPath()
                + request.getRequestURI()
                + (request.getQueryString().equals("") ? "" : "?" + request.getQueryString());
    }

    /**
     * url编码
     * @param url
     * @return
     */
    public static String encodeUrl(String url){
        try {
            String encodeURL = URLEncoder.encode( url, "UTF-8" );
            return encodeURL;

        } catch (UnsupportedEncodingException e) {
            throw new CheckException(e.getMessage());
        }
    }

    /**
     * url解码
     * @param url
     * @return
     */
    public static String decodeUrl(String url){
        try {
            String decodeURL  = URLDecoder.decode( url, "UTF-8" );
            return decodeURL;
        } catch (UnsupportedEncodingException e) {
            throw new CheckException(e.getMessage());
        }
    }
}
